package com.easychat.aspect;

import com.easychat.annotation.GlobalInterceptor;
import com.easychat.common.LeaseException;
import com.easychat.dto.TokenUserInfoDto;
import com.easychat.entity.LoginUser;
import com.easychat.entity.constants.Constants;
import com.easychat.enums.ExceptionCodeEnum;
import com.easychat.utils.LoginUserHolder;
import com.easychat.utils.StringTools;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author 10 2024/10/8
 */
@Aspect
@Component
public class GlobalOperationAspect {
    @Resource
    private RedisTemplate redisTemplate;

//    @Before("@annotation(com.easychat.annotation.GlobalInterceptor)")
//    public void interceptorDo(JoinPoint point){
//        try{
//            Method method = ((MethodSignature) point.getSignature()).getMethod();
//            GlobalInterceptor interceptor = method.getAnnotation(GlobalInterceptor.class);
//            if(interceptor == null){
//                return;
//            }
//            if(interceptor.checkLogin() || interceptor.checkAdmin()){
//                checkLogin(interceptor.checkAdmin());
//            }
//
//        }catch (Exception e){
//            throw new LeaseException(ExceptionCodeEnum.ERROR_LATER);
//        }catch (Throwable e){
//            throw new LeaseException(ExceptionCodeEnum.ERROR_LATER);
//        }
//    }
//    @After("@annotation(com.easychat.annotation.GlobalInterceptor)")
//    public void afterClean(){
//        if(LoginUserHolder.get() != null){
//            LoginUserHolder.clear();
//        }
//    }

    @Around("@annotation(com.easychat.annotation.GlobalInterceptor)") // 替换为你的切入点表达式
    public Object checkLoginAndClearThreadLocal(ProceedingJoinPoint point) {
        Object result = null; // 用于存放方法的返回结果

        try {
            Method method = ((MethodSignature) point.getSignature()).getMethod();
            GlobalInterceptor interceptor = method.getAnnotation(GlobalInterceptor.class);

            if (interceptor != null) {
                if (interceptor.checkLogin() || interceptor.checkAdmin()) {
                    checkLogin(interceptor.checkAdmin()); // 进行登录校验
                }
            }

            result = point.proceed(); // 执行目标方法

        } catch (Exception e) {
            throw new LeaseException(ExceptionCodeEnum.ERROR_LATER);
        } catch (Throwable e) {
            throw new LeaseException(ExceptionCodeEnum.ERROR_LATER);
        } finally {
            // 清理 ThreadLocal
            if (LoginUserHolder.get() != null) {
                LoginUserHolder.clear();
            }
        }

        return result; // 返回目标方法的结果
    }

    private void checkLogin(Boolean checkAdmin){
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        if(StringTools.isEmpty(token)){
            throw new LeaseException(ExceptionCodeEnum.NOT_LOG);
        }
        TokenUserInfoDto tokenUserInfoDto = (TokenUserInfoDto) redisTemplate.opsForValue().get(Constants.REDIS_KEY_WS_TOKEN + token);
        if(tokenUserInfoDto == null){
            throw new LeaseException(ExceptionCodeEnum.NOT_LOG);
        }
        if(checkAdmin && !tokenUserInfoDto.getAdmin()){
            throw new LeaseException(ExceptionCodeEnum.NOT_THIS_URL);
        }
        LoginUserHolder.set(tokenUserInfoDto);
    }
}
